﻿using Colorful.API;
using Colorful.CMS.Core.Controllers.Admin;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Colorful.CMS.Core
{
    public class RouteConvention : IApplicationModelConvention
    {
        //private readonly AttributeRouteModel _languagePrefix;
        private readonly AttributeRouteModel _adminPrefix;
        private readonly AttributeRouteModel _apiPrefix;

        public RouteConvention()
        {
            //if (WebService.Languages.Count > 1)
            //    _languagePrefix = new AttributeRouteModel(new RouteAttribute("{lang:regex(^[cCnNeE]{{2}}$)}")); //{lang:regex(^[[a-z]]{{2}}-[[A-Z]]{{2}}$)}
            _adminPrefix = new AttributeRouteModel(new RouteAttribute(WebService.AdminRoutePrefix));
            _apiPrefix = new AttributeRouteModel(new RouteAttribute("api"));
        }

        public void Apply(ApplicationModel application)
        {
            var baseControllers = application.Controllers.Where(a => a.ControllerType.BaseType.FullName.StartsWith("Colorful.CMS.Core.Controllers.Admin.") && a.ControllerType.BaseType.FullName != "Colorful.CMS.Core.Controllers.Admin.AdminBaseController").ToList();
            foreach (var controller in application.Controllers)
            {
                if (baseControllers.Any(a => a.ControllerType.BaseType.Equals(controller.ControllerType)))
                {
                    foreach (var action in controller.Actions)
                    {
                        foreach (var selector in action.Selectors)
                            selector.AttributeRouteModel = null;
                    }
                    continue;
                }
                var controllerName = controller.ControllerName;
                if (controllerName == "Base" || controllerName == "WebBase" || controllerName == "BaseAPI"
                    || controllerName == "AdminBase" || controllerName == "Error" || controllerName == "UEditor")
                    continue;
                if (controller.ControllerName == "Home")
                {
                    Console.WriteLine("home");
                }
                var isAdminController = controller.ControllerType.BaseType.Equals(typeof(AdminBaseController)) || baseControllers.Contains(controller);
                var isAPI = controller.ControllerType.BaseType.Equals(typeof(BaseAPI));
                #region ControllerRoutes
                var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
                if (matchedSelectors.Any())
                {
                    foreach (var selectorModel in matchedSelectors)
                    {
                        if (isAdminController)
                            selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_adminPrefix, selectorModel.AttributeRouteModel);
                        else if (isAPI)
                            selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_apiPrefix, selectorModel.AttributeRouteModel);
                        else if (WebService.Languages.Count > 1)
                        {
                            var langRouteModel = new AttributeRouteModel(new RouteAttribute($"{{lang:regex(^[cCnNeE]{{2}}$)}}/{selectorModel.AttributeRouteModel.Name}"));
                            selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(langRouteModel, selectorModel.AttributeRouteModel);
                        }
                    }
                }
                var unmatchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
                if (unmatchedSelectors.Any() && !(!isAdminController && controllerName == "Home"))
                {
                    foreach (var selectorModel in unmatchedSelectors)
                    {
                        if (isAdminController)
                        {
                            selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_adminPrefix, selectorModel.AttributeRouteModel);
                        }
                        else if (WebService.Languages.Count > 1)
                        {
                            var langRouteModel = new AttributeRouteModel(new RouteAttribute($"{{lang:regex(^[cCnNeE]{{2}}$)}}/{controllerName}"));
                            selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(langRouteModel, selectorModel.AttributeRouteModel);
                        }
                        else
                            selectorModel.AttributeRouteModel = new AttributeRouteModel(new RouteAttribute(controllerName));
                    }
                }
                #endregion

                #region ActionRoutes
                foreach (var action in controller.Actions)
                {
                    var selectors = action.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
                    if (selectors.Any())
                    {
                        foreach (var selector in selectors)
                        {
                            if (!isAdminController && action.ActionName.ToLower() == "index")
                                continue;
                            string url;
                            if (action.ActionName.ToLower() == "index")
                                url = controllerName;
                            else
                                url = action.ActionName;
                            selector.AttributeRouteModel = new AttributeRouteModel(new RouteAttribute(url));
                            //if (controllerName != "Home")
                            //{
                            //    string url;
                            //    if (action.ActionName.ToLower() == "index")
                            //        url = controllerName;
                            //    else
                            //        url = $"{controllerName}/{action.ActionName}";
                            //    selector.AttributeRouteModel = new AttributeRouteModel(new RouteAttribute(url));
                            //}
                            //else
                            //{
                            //    selector.AttributeRouteModel = new AttributeRouteModel(new RouteAttribute(action.ActionName));
                            //}
                        }
                    }
                    //else if (isAdminController && action.ActionName.ToLower() == "index")
                    //{
                    //    var selector = action.Selectors.Where(x => x.AttributeRouteModel != null).FirstOrDefault();
                    //    selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_adminPrefix, selector.AttributeRouteModel);
                    //}
                }
                #endregion
            }
        }
    }
}